package com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-04-29 21:03.
 *
 * @Description 代理类
 * 定义实现 InvocationHandler 接口的调用处理器对象，它是对拦截器的实现。
 * 从JDK1.3开始，java提供了对动态代理的支持，java实现动态代理需要用到java.lang.reflect包的一些类（Proxy类，InvocationHandler接口）
 * <p/>
 * InvocationHandler 对于 Proxy，就如同 Runnable 对于 Thread。
 * InvocationHandler 接口中只有一个方法 invoke，它的作用就跟 Runnable 中的 run 方法类似，定义了代理对象在执行真实对象的方法时所希望执行的动作，其原型如下：
 * Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 * 其中的参数解释：
 * proxy：表示执行这个方法的代理对象
 * method：表示真实对象实际需要执行的方法
 * args：表示真实对象实际执行方法时所需的参数
 */

public class FilterHandler implements InvocationHandler {
    // 要代理的原始真实对象
    private String className;

    /**
     * Alt+Insert 添加构造函数
     *
     * @param className 要代理的真实对象
     */
    public FilterHandler(String className) {
        this.className = className;
    }

    /**
     * 拦截器：这是对拦截器的实现，常用于权限
     *
     * @param proxy  表示执行这个方法的代理对象
     * @param method 表示真实对象实际需要执行的方法
     * @param args   表示真实对象实际执行方法时所需的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (className.endsWith("Action")) {
            System.out.println("我在执行这个方法：" + className + "." + method.getName());
            // 调用原始的真实对象
            return method.invoke(Class.forName(className).newInstance(), args);
        } else {
            System.out.println("类 " + className + " 不是以 Action 结尾的，驳回请求。");
            return null;
        }
    }
}
